using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;

public class Player : MonoBehaviour
{
    // Start is called before the first frame update
    private Vector3 m_Dir;
    [FormerlySerializedAs("MapSDF")] public Texture2D m_MapSDF;
    private Color[] m_Map;
    private float m_Radius;   //地图上的半径数
    private float[] m_Grid;
    void Start()
    {
        m_Map = m_MapSDF.GetPixels();
        m_Radius = transform.localScale.x / 2.0f / MapTextureCreate.MapSize[0] * MapTextureCreate.MapTextureSize[0];
        Debug.Log("本体半径：" + m_Radius);
        m_Grid = new float[2] { MapTextureCreate.MapSize[0] / MapTextureCreate.MapTextureSize[0], MapTextureCreate.MapSize[1] / MapTextureCreate.MapTextureSize[1] };
    }

    // Update is called once per frame
    void Update()
    {
        m_Dir = Vector3.zero;
        if (Input.GetKey(KeyCode.W))
        {
            m_Dir.z = 1;
        }
        else if (Input.GetKey(KeyCode.S))
        {
            m_Dir.z = -1;
        }

        if (Input.GetKey(KeyCode.A))
        {
            m_Dir.x = -1;
        }
        else if (Input.GetKey(KeyCode.D))
        {
            m_Dir.x = 1;
        }
        if (m_Dir != Vector3.zero)
            Move();

        // if (Input.GetKeyDown(KeyCode.Q))
        // {
        //     m_Tem = new Texture2D(257, 257);
        //     m_Tem.SetPixels(m_Map);
        //     m_Tem.Apply();
        // }
    }

    // [FormerlySerializedAs("tem")] public Texture2D m_Tem;

    private void Move()
    {
        m_Dir = m_Dir * 0.01f;
        Vector3 vec = transform.position + (m_Dir);
        //判断是不是sdf碰撞区域
        ////在画布上左下角的坐标
        if (!IsBarrier(vec))
        {
            transform.position = vec;
        }
        else
        {
            Vector2 mTempDir = new Vector2(m_Dir.x, m_Dir.z).normalized;
            var position = transform.position;
            Vector2 gradient = Gradient(new Vector2(position.x, position.z));
            float dot = Vector2.Dot(gradient, mTempDir);
            if (dot > 0)
            { //代表反向
                transform.position = vec;
                return;
            }

            Vector2 adjustdir = mTempDir - gradient * Vector2.Dot(gradient, mTempDir);
            vec = transform.position + new Vector3(adjustdir.x, 0, adjustdir.y).normalized * 0.01f;
            for (int i = 0; i < 3; i++)
            {
                var dis = MapDis(vec);
                if (dis >= m_Radius)
                {
                   break;
                }
                var t = Gradient(new Vector2(vec.x, vec.z)).normalized;

                vec += (new Vector3(t.x, 0, t.y).normalized * ((m_Radius - dis)) / MapTextureCreate.MapTextureSize[0] * MapTextureCreate.MapSize[0]);

                if (vec.x > 10 || vec.y > 10 || vec.x < 0 || vec.y < 0)
                {
                    return;
                }
            }
            transform.position = vec;
        }
    }


    //是不是障碍物
    private bool IsBarrier(Vector3 pos)
    {
        if (m_Radius < MapDis(pos))
        {
            return false;
        }
        return true;
    }
    //test
    //查表操作
    private float MapDis(Vector3 pos)
    {
        float x = pos.x / m_Grid[0];
        float y = pos.z / m_Grid[1];
        int fx = (int)x;
        int fy = (int)y;
        float rx = x - fx;
        float ry = y - fy;
        int i = fy * (m_MapSDF.width) + fx;
        //双线性差值
        float distanceField = (1 - rx) * (1 - ry) * m_Map[i].r + rx * (1 - ry) * m_Map[i + 1].r + (1 - rx) * ry * m_Map[i + m_MapSDF.height].r + rx * ry * m_Map[i + (m_MapSDF.height + 1)].r;
        distanceField = distanceField * 256; //像素转成成texture上的实际距离
        return distanceField;
    }

    private Vector2 Gradient(Vector3 pos)
    {
        float delta = 0.1f;
        Vector2 a = 0.5f * new Vector2(MapDis(new Vector3(pos.x + delta, 0, pos.y)) - MapDis(new Vector3(pos.x - delta, 0, pos.y)),
                                  MapDis(new Vector3(pos.x, 0, pos.y + delta)) - MapDis(new Vector3(pos.x, 0, pos.y - delta)));
        a.x = (float)Math.Round(a.x, 1);
        a.y = (float)Math.Round(a.y, 1);
        Vector2 ss = a.normalized;
        return ss;
    }

}
